package gov.pbc.nn.kjgl.meetings.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.task.Task;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.bdf.service.DeptService;
import gov.pbc.nn.core.dao.AbstractHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.entity.Meeting;
import gov.pbc.nn.kjgl.entity.MeetingDept;
import gov.pbc.nn.kjgl.entity.MeetingUser;
import gov.pbc.nn.kjgl.train.dao.TrainRegisterJdbcDao;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

@Repository
public class MeetingDao extends AbstractHibernateDao {

	@Autowired
	private DeptService deptService;

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Autowired
	private TrainRegisterJdbcDao trainRegisterJdbcDao;

	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao CoreHibernateDao;

	/**
	 * 根据会议审核员和部门处长获取相应的审核会议
	 * 
	 * @param page
	 */
	public void getMeetingByCommit(Page<Meeting> page, Criteria criteria) {

		String username = ContextHolder.getLoginUserName();
		if (SecurityUtils.containsRole(username, Constants.ROLE_HYSHY)) {
			DetachedCriteria query = this.buildDetachedCriteria(criteria, Meeting.class);
			query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
			query.add(Restrictions.eq("state", 5));
			query.add(Restrictions.eq("assessorId", ContextHolder.getLoginUserName()));
			query.addOrder(Order.desc("updateDate"));
			this.pagingQuery(page, query);
		}
		if (page.getEntityCount() == 0) {
			// if (SecurityUtils.containsRole(username, Constants.ROLE_CZ)) {
			DetachedCriteria query = this.buildDetachedCriteria(criteria, Meeting.class);
			query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
			query.add(Restrictions.eq("state", 12));
			// query.add(Restrictions.like("applyDeptId",
			// ContextHolder.getLoginUser().getDepts().get(0).getId(),MatchMode.START));
			query.add(Restrictions.eq("czUsername", ContextHolder.getLoginUserName()));
			query.addOrder(Order.desc("updateDate"));
			this.pagingQuery(page, query);
			// }
		}
	}

	/**
	 * 获取当前登录人所属处室中的会议审核员
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getAssessor() {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(),
				Constants.ROLE_HYSHY);
		List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
		for (IUser u : users) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cname", u.getCname());
			map.put("username", u.getUsername());
			map.put("dept", EntityUtils.getValue(u, "deptName"));
			ls.add(map);
		}
		return ls;
	}

	/**
	 * 维护Meeting
	 * 
	 * @param meeting
	 */
	public void saveMeeting(Meeting meeting) {
		if (EntityUtils.getState(meeting).equals(EntityState.NEW)) {
			// State设置为1表示状态为新建
			meeting.setState(1);
			meeting.setApplyUser(ContextHolder.getLoginUserName());
			meeting.setApplyDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
			this.save(meeting);
		} else if (EntityUtils.getState(meeting).equals(EntityState.MODIFIED)) {
			this.update(meeting);
		}
	}

	/**
	 * 提交单条数据
	 */
	public void saveOneMeeting(Meeting meeting) {
		meeting.setState(5);
		meeting.setApplyUser(ContextHolder.getLoginUserName());
		meeting.setApplyDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		if (EntityUtils.getState(meeting).equals(EntityState.NEW)) {
			this.save(meeting);
		} else if (EntityUtils.getState(meeting).equals(EntityState.MODIFIED)) {
			this.update(meeting);
		}

	}

	/**
	 * 根据id删除Meeting
	 * 
	 * @param id
	 */
	public void deleteMeeting(String id) {
		// 删除Meeting
		this.delete(id, Meeting.class);
		// 删除对应的MeetingUser
		List<MeetingUser> ls = getMeetingUserByMeetingid(id);
		if (ls != null) {
			for (MeetingUser m : ls) {
				this.delete(m);
			}
		}
		// 删除对应的MeetingDept
		List<MeetingDept> lsd = getMeetingDeptByMeetingid(id);
		if (lsd != null) {
			for (MeetingDept m : lsd) {
				this.delete(m);
			}
		}
	}

	/**
	 * 根据MeetingId获取MeetingUser
	 * 
	 * @param id
	 * @return
	 */

	public List<MeetingUser> getMeetingUserByMeetingid(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(MeetingUser.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("meetingId", id));
		List<MeetingUser> ls = (List<MeetingUser>) this.query(query);
		if (ls.size() > 0) {
			return ls;
		}
		return null;
	}

	public List<MeetingDept> getMeetingDeptByMeetingid(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(MeetingDept.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("meetingId", id));
		List<MeetingDept> ls = (List<MeetingDept>) this.query(query);
		if (ls.size() > 0) {
			return ls;
		}
		return null;
	}

	/**
	 * 根据id查询Meeting
	 * 
	 * @param id
	 * @return
	 */
	public Meeting selectMeetingById(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(Meeting.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("id", id));
		List<Meeting> ls = (List<Meeting>) this.query(query);
		if (ls.size() > 0) {
			return ls.get(0);
		}
		return null;
	}

	/**
	 * 提交审核
	 * 
	 * @param meeting
	 */
	public void commitMeeting(Meeting meeting) {
		// state设置为5表示已提交
		meeting.setState(5);
		this.update(meeting);
	}

	/**
	 * 审核同意
	 * 
	 * @param meeting
	 * @param opinion
	 * @param i
	 */
	public void agree(Meeting meeting, String opinion, int i, String czName, String czUsername) {
		// i 为0时表示不需要处长审核，1表示需要处长审核,3表示当前登录人同时拥有处长和会议管理员两个岗位时，同意申请
		// state设置为10表示已同意申请
		// state设置为12表示处领导审核状态
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		;
		List<IUser> ls = SecurityUtils.getUserByRoleForDept(dept.getCDept().getId(), Constants.ROLE_CZ);
		for (IUser u : ls) {
			if (ContextHolder.getLoginUserName().equals(u.getUsername())) {
				i = 3;
			}
		}
		if (i == 1) {
			meeting.setState(12);
			meeting.setCldSh(i);
			meeting.setCzName(czName);
			meeting.setCzUsername(czUsername);
		} else if (i == 3) {
			meeting.setState(10);
			meeting.setCldSh(1);
			meeting.setCzName(ContextHolder.getLoginUser().getCname());
			meeting.setCzUsername(ContextHolder.getLoginUserName());
		} else {
			meeting.setState(10);
			meeting.setCldSh(i);
		}
		this.update(meeting);
		final Opinion o = new Opinion();
		o.setOpinion(opinion);
		o.setBusKey(meeting.getId());
		o.setBusTable("T_MEETING");
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCreateUser(ContextHolder.getLoginUserName());
		o.setCreateDate(new Date());
		this.CoreHibernateDao.save(o);
	}

	/**
	 * 审核不同意
	 * 
	 * @param meeting
	 * @param opinion
	 */
	public void disagree(Meeting meeting, String opinion) {
		// state设置为11表示不同意申请
		meeting.setState(11);
		meeting.setCldSh(0);
		this.update(meeting);
		final Opinion o = new Opinion();
		o.setOpinion(opinion);
		o.setBusKey(meeting.getId());
		o.setBusTable("T_MEETING");
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.CoreHibernateDao.save(o);
	}

	/**
	 * 发布会议报名任务
	 * 
	 * @param parameter
	 */
	public void releaseMeeting(Map<String, Object> parameter) {
		// state设置为15表示发布
		Meeting m = this.selectMeetingById((String) parameter.get("meeting"));
		m.setState(15);
		this.update(m);
		List<String> ids = (List<String>) parameter.get("ids");
		List<String> names = (List<String>) parameter.get("names");
		// Date begin = (Date) parameter.get("beginTime");
		// Date end = (Date) parameter.get("endTime");
		for (int i = 0; i < ids.size(); i++) {
			if (this.checkMeetingDept(ids.get(i), m.getId()) == null) {
				MeetingDept md = new MeetingDept();
				md.setDeptId(ids.get(i));
				md.setDeptName(names.get(i));
				md.setMeetingId(m.getId());
				// md.setBeginTime(begin);
				// md.setEndTime(end);
				this.save(md);
			} else {
				MeetingDept md = this.checkMeetingDept(ids.get(i), m.getId());
				// md.setBeginTime(begin);
				// md.setEndTime(end);
				this.update(md);
			}
		}
	}

	/**
	 * 添加参会人员
	 * 
	 * @param meeting
	 * @param parameter
	 */
	public void insertMeetingUser(Meeting meeting, Map<String, Object> parameter) {
		int i = checkMeetingUser((String) parameter.get("username"), meeting.getId());
		Dept d = (Dept) SecurityUtils.getZZByUser((String) parameter.get("username"));
		int nnpbcNum = meeting.getNnpbcNum();// 南宁中支人数
		int dszzNum = meeting.getDszzNum();// 地市中支人数
		int nnxzhNum = meeting.getNnxzhNum();// 南宁市县支行人数
		int outUnitNum = meeting.getOutUnitNum();// 外单位人数
		int allNum = meeting.getAllNum();// 人数合计

		if (i < 1) {
			MeetingUser mr = new MeetingUser();
			mr.setUserName((String) parameter.get("username"));
			mr.setUserCname((String) parameter.get("cname"));
			mr.setUserEname((String) parameter.get("ename"));
			mr.setMeetingId(meeting.getId());
			mr.setJoin(true);
			this.save(mr);

			if (d.getLevel() == 0) {
				nnpbcNum++;
				meeting.setNnpbcNum(nnpbcNum);
			} else if (d.getLevel() == 1) {
				nnxzhNum++;
				meeting.setNnxzhNum(nnxzhNum);
			} else if (d.getLevel() == 2) {
				dszzNum++;
				meeting.setDszzNum(dszzNum);
			} else if (d.getLevel() == 3) {
				nnxzhNum++;
				meeting.setNnxzhNum(nnxzhNum);
			} else {
				outUnitNum++;
				meeting.setOutUnitNum(outUnitNum);
			}
			allNum = nnpbcNum + dszzNum + nnxzhNum + outUnitNum + meeting.getMeetNum() + meeting.getOther();
			meeting.setAllNum(allNum);

			this.update(meeting);
		}
	}

	/**
	 * 判断参会人员是否重复
	 * 
	 * @param username
	 * @param meetingId
	 * @return
	 */
	public int checkMeetingUser(String username, String meetingId) {
		String hql = "select count(*) from MeetingUser where meetingId=:meetingId and userName=:username and invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("meetingId", meetingId);
		map.put("username", username);
		return this.queryForInt(hql, map);
	}

	/**
	 * 判断发布部门是否重复
	 * 
	 * @param deptId
	 * @param meetingId
	 * @return
	 */
	public MeetingDept checkMeetingDept(String deptId, String meetingId) {
		String hql = "from MeetingDept where meetingId=:meetingId and deptId=:deptId and invalid=false";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("deptId", deptId);
		map.put("meetingId", meetingId);
		List<MeetingDept> ls = this.query(hql, map);
		if (ls.size() > 0) {
			return ls.get(0);
		} else {
			return null;
		}
	}

	/**
	 * 撤销会议申请
	 * 
	 * @param meeting
	 */
	public void backMeeting(Meeting meeting) {
		// state设置为20表示已撤销
		meeting.setState(20);
		this.update(meeting);
	}

	/**
	 * 根据MeetingId获取参会人员
	 * 
	 * @param id
	 * @return
	 */
	public List<Map<String, Object>> getMeetingXq(String id) {
		String hql = "from MeetingUser where meetingId=:meetingId and invalid=false";
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("meetingId", id);
		List<MeetingUser> lsUser = this.query(hql, param);
		List<Map<String, Object>> meetingXq = new ArrayList<Map<String, Object>>();
		if (!lsUser.isEmpty()) {
			for (MeetingUser mu : lsUser) {
				Map<String, Object> value = new HashMap<String, Object>();
				value.put("id", mu.getId());
				value.put("muId", mu.getId());
				value.put("join", mu.getJoin());
				value.put("cname", mu.getUserCname());
				Map<String, Object> deptname = new HashMap<String, Object>();
				List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
				ls = trainRegisterJdbcDao.getDept(mu.getUserName());
				deptname = ls.get(0);
				value.put("deptName", deptname.get("deptName"));
				meetingXq.add(value);
			}
		}
		return meetingXq;
	}

	/**
	 * 根据MeetingId判断相应的发布时间
	 * 
	 * @param id
	 * @return
	 */
	public boolean getMeetingDeptByMeetingId(String id) {
		String hql = "select endTime from MeetingDept where meetingId=:meetingId and deptId=:deptId and invalid=false";
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("meetingId", id);
		param.put("deptId", ContextHolder.getLoginUser().getDepts().get(0).getId());
		List<Date> ls = this.query(hql, param);
		if (!ls.isEmpty()) {
			Date d = new Date();
			Date endTime = ls.get(0);
			if (d.getTime() <= endTime.getTime()) {
				return true;
			}
			return false;
		}
		return true;
	}

	/**
	 * 维护MeetingUser
	 * 
	 * @param muId
	 */

	public void saveMeetingUser(String muId, Boolean join) {
		MeetingUser mu = this.getMeetingUserById(muId);
		mu.setJoin(join);
		this.update(mu);
	}

	/**
	 * 通过Id获取MeetingUser
	 * 
	 * @param id
	 * @return
	 */
	public MeetingUser getMeetingUserById(String id) {
		DetachedCriteria query = DetachedCriteria.forClass(MeetingUser.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("id", id));
		List<MeetingUser> ls = (List<MeetingUser>) this.query(query);
		if (!ls.isEmpty()) {
			return ls.get(0);
		}
		return null;
	}

	/**
	 * 根据id删除参会人员
	 * 
	 * @param id
	 */
	public void deleteMeetingUser(String id) {
		MeetingUser mu = this.getMeetingUserById(id);
		Dept d = (Dept) SecurityUtils.getZZByUser(mu.getUserName());
		Meeting meeting = this.selectMeetingById(mu.getMeetingId());
		int nnpbcNum = meeting.getNnpbcNum();// 南宁中支人数
		int dszzNum = meeting.getDszzNum();// 地市中支人数
		int nnxzhNum = meeting.getNnxzhNum();// 南宁市县支行人数
		int outUnitNum = meeting.getOutUnitNum();// 外单位人数
		int allNum = meeting.getAllNum();// 人数合计

		if (d.getLevel() == 0) {
			nnpbcNum--;
			meeting.setNnpbcNum(nnpbcNum);
		} else if (d.getLevel() == 1) {
			nnxzhNum--;
			meeting.setNnxzhNum(nnxzhNum);
		} else if (d.getLevel() == 2) {
			dszzNum--;
			meeting.setDszzNum(dszzNum);
		} else if (d.getLevel() == 3) {
			nnxzhNum--;
			meeting.setNnxzhNum(nnxzhNum);
		} else {
			outUnitNum--;
			meeting.setOutUnitNum(outUnitNum);
		}
		allNum = nnpbcNum + dszzNum + nnxzhNum + outUnitNum + meeting.getMeetNum() + meeting.getOther();
		meeting.setAllNum(allNum);
		this.update(meeting);
		this.delete(id, MeetingUser.class);
	}

	public List<Opinion> getOpinion(String id) {
		List<Opinion> values = UfloUtils.getOpinions(null, id, null, null, null);
		return values;
	}
}
